#!/usr/bin/env python
# encoding: utf-8
"""
IndexManager.py

"""

import os
import sys
import re
import cPickle

import DataManager
import settings

class Index(object):
	"""
	Index:
	Implements basic methods for building inverted indexes.
	"""
	def __init__(self, corpus, name, source):
	    self.corpusName = corpus
	    self.indexName = name
	    self.indexSource = os.path.join(settings.CORPUS_PATH, source)
	    self.lexicon = {}
	    self.index = {}
	    self.indexData = {'Corpus':self.corpusName, 'Name':self.indexName, 'Source':self.indexSource, 
	                      'Index': self.index, 'Lexicon': self.lexicon}
	    try:
	        os.chdir(os.path.join(settings.CORPUS_PATH))
	    except:
	        raise EnvironmentError('No corpora folder found!')
	
	def _register(self):
	    """ register index to a specific corpus """
	    meta = cPickle.load(open(settings.DATA_PATH+'corpora', 'r'))
	    if meta.has_key(self.corpusName):
	        indexList = meta[self.corpusName]
	        indexList.append('_'+self.corpusName+'_'+self.indexName)
	        meta[self.corpusName] = indexList
	        cPickle.dump(meta, open(settings.DATA_PATH+'corpora', 'w'))
	    else:
	        raise KeyError, "Unknown Corpus"
	    
	    return
	
	def _parseDirectory(self, sourceDir):
		""" parsing a directory, calls parseSingelFile for every file """
		for x in sourceDir:
			self.parseSingleFile(x) # TODO fix method
    
	def _prepareInputSource(self):
		""" check for directory or file, returns list of dirs or string """
		for x in self.indexSource:
			if os.path.isdir(x):
				return os.listdir(x)
			elif os.path.isfile(x):
				return x
			else:
				raise IOError, "Select Directory or File"
		return
	
	def updateStandardIndex(self, input):
	    pass
	
	def updatePositionalIndex(self, input):
		""" 
		Index:
		Dictionary
		Input must be tuple with: (token, docID, posting) """
		if self.index.has_key(input[0]):                                    # token already seen
			postingDict = self.index[input[0]]                              # list of posting tuples, means the dif. docs the token is in
			if postingDict.has_key(input[1]):                               # docID / token combination already seen 
			    list = postingDict[1][1]                                    # copy postings
			    list.append(input[2])                                       # update postings with new position
			    # finally write it back 
			    #          -token / docID      = (           count+1,                postings)
			    self.index[input[0]][input[1]] = (self.index[input[0]][input[1]][0] + 1, list)
		else:
			self.index[input[0]] = { input[1]: (1, [input[2]]) }            # new posting: index {token: {docID: (#,[posting])}
		return

	def updateLexicon(self, input):
		""" 
		Lexicon:
		Dictionary with { token:num(token) }
    	feed updateLexicon with tuples (token)
		update lexicon dict with new token or increase num 
		"""
		if self.lexicon.has_key(input[0]):
			self.lexicon[input[0]] = self.lexicon[input[0]] + 1
		else:
			self.lexicon[input[0]] = 1
		return
    
	def save(self):
		""" 
		save index data to disc:
		data corpus, index name, index, lexicon
		"""
		self._register()
		cPickle.dump(self.indexData, open(settings.DATA_PATH+'_'+str(self.corpusName)+'_'+str(self.indexName), 'w'))
	
	def __str__(self):
	    return "Info: Index '%s' from '%s' corpus at _%s_." % (self.indexData['Name'], self.indexData['Corpus'], self.indexData['Source'])
    
if __name__ == "__main__":

	print 'IndexManager'